package controllers.data;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import models.EntityContainer;
import models.Target;
import uk.ac.shef.wit.simmetrics.similaritymetrics.JaroWinkler;

import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;

import controllers.data.providers.Mql;
import controllers.data.providers.Sparql;


public class RequestBuilder
{
    public static Set<EntityContainer> search(String query, Target target)
    {
        switch(target.type()) {
            case sparql:
                return sparql_search(query, target);
            case mql:
                return mql_search(query, target);
        }
        return null;
    }


    private static Set<EntityContainer> sparql_search(String query, Target target)
    {
        query = Sparql.removeIllegalCharacters(query);

        Set<EntityContainer> result = new HashSet<>();
        JaroWinkler jw = new JaroWinkler();

        List<QuerySolution> queryResult = Sparql.query("SELECT DISTINCT ?s {?s rdfs:label ?o . ?o <bif:contains> \"'" + query + "'\" . }", target);

        // If nothing is found, return an empty result set
        if(queryResult == null) { return result; }
        for(QuerySolution qs : queryResult) {
            // When querying e.g. for Plato on Yago, an instance is returned that has no subject. We want to be safe from that.
            if(!qs.contains("s"))
                continue;
            RDFNode n = qs.get("s");
            if(n instanceof Resource) {
                EntityContainer ec = new EntityContainer(qs.getResource("s"), target);
                ec.setConfidence(jw.getSimilarity(query, ec.getLocalName()));
                result.add(ec);
            }
        }

        return result;
    }


    private static Set<EntityContainer> mql_search(String query, Target target)
    {
        return Mql.query(query, target.url() + Mql.FREEBASE_SEARCH);
    }

}